package com.wjy.myokhttp.net;

import android.util.Log;

import com.google.gson.JsonObject;
import com.wjy.myokhttp.application.MyApplication;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by wjy.
 * Date: 2019/11/22
 * Time: 9:45
 * Describe: Retrofit网络请求工具类,用于初始化Retrofit，设置请求API的baseUrl、gson解析方式
 */
public class RetrofitHelper {

    private static RetrofitHelper instance = null;
    private static OkHttpClient okHttpClient;
    private ApiService apiService;

    public RetrofitHelper(OkHttpClient okHttpClient){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(ApiService.BASE_URL)//服务器地址
                .addConverterFactory(GsonConverterFactory.create())//用Gson把服务端返回的json数据解析成实体
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(okHttpClient)
                .build();//生成一个Retrofit实例
        apiService = retrofit.create(ApiService.class);//传入网络接口类,得到接口对象实例,调用接口类中的方法。
    }

    public static RetrofitHelper getInstance(){
        if (instance == null){
            instance = new RetrofitHelper(getOkhttpClient());
        }
        return instance;
    }

    //okhttp连接的一些设置
    public static OkHttpClient getOkhttpClient(){
        okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(20, TimeUnit.SECONDS)//连接超时时间
                .readTimeout(20,TimeUnit.SECONDS)//读超时时间
                .writeTimeout(20,TimeUnit.SECONDS)//写超时时间
                .retryOnConnectionFailure(true)//失败重连
                .addInterceptor(loggingInterceptor)
                .addInterceptor(headerInterceptor)//设置头信息
//                .addInterceptor()//设置拦截器
                .cache(cache).addInterceptor(cacheInterceptor)//设置缓存
                .build();
        return okHttpClient;
    }

    //日志
    static HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
        @Override
        public void log(String message) {
            //打印retrofit日志
            Log.e("RetrofitLog", "retrofitBack = " + message);
        }
    });

    /**
     * 设置头信息
     */
    static Interceptor headerInterceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request originalRequest = chain.request();
            Request.Builder requestBuilder = originalRequest.newBuilder()
//                    .addHeader("Accept-Encoding", "gzip")
                    .addHeader("Accept", "application/json")
                    .addHeader("Content-Type", "text/plain; charset=utf-8")
                    .method(originalRequest.method(), originalRequest.body());
            Request request = requestBuilder.build();
            return chain.proceed(request);
        }
    };

    /**
     * 设置缓存
     */
    public static final String CACHE_NAME = "MyCache";
    static File cacheFile = new File(MyApplication.context.getExternalCacheDir(), CACHE_NAME);
    static Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);
    static Interceptor cacheInterceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            if (!NetWorkUtil.isNetworkConnected()) {
                request = request.newBuilder()
                        .cacheControl(CacheControl.FORCE_CACHE)
                        .build();
            }
            Response response = chain.proceed(request);
            if (!NetWorkUtil.isNetworkConnected()) {
                int maxAge = 0;
                // 有网络时 设置缓存超时时间0个小时
                response.newBuilder()
                        .header("Cache-Control", "public, max-age=" + maxAge)
                        .removeHeader(CACHE_NAME)// 清除头信息，因为服务器如果不支持，会返回一些干扰信息，不清除下面无法生效
                        .build();
            } else {
                // 无网络时，设置超时为4周
                int maxStale = 60 * 60 * 24 * 28;
                response.newBuilder()
                        .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                        .removeHeader(CACHE_NAME)
                        .build();
            }
            return response;
        }
    };

    //=========================以下是  通过接口对象,调用接口类中的方法================================//

    public Observable<JsonObject> requestData(String url){
        return apiService.requestData(url);
    }

    public Observable<JsonObject> requestLogin_get(String username,String pwd,String regid){
        return apiService.requestLogin_get(username,pwd,regid);
    }

    public Observable<JsonObject> requestLogin_post(String username,String pwd,String regid){
        return apiService.requestLogin_post(username,pwd,regid);
    }

    public Observable<JsonObject> requestLogin_get_map(Map<String,String> params){
        return apiService.requestLogin_get_map(params);
    }

    public Observable<JsonObject> requestLogin_post_map(Map<String,String> params){
        return apiService.requestLogin_post_map(params);
    }

    public Observable<JsonObject> requestLogin_post_body(ApiService.LoginInfo loginInfo){
        return apiService.requestLogin_post_body(loginInfo);
    }

    public Observable<JsonObject> requestLogin_get_http(String username,String pwd,String regid){
        return apiService.requestLogin_get_http(username,pwd,regid);
    }

    public Observable<JsonObject> requestLogin_post_http(String username,String pwd,String regid){
        return apiService.requestLogin_post_http(username,pwd,regid);
    }

    public Observable<JsonObject> uploadImage(String tp,String code){
        return apiService.uploadImage(tp,code);
    }

    public Observable<JsonObject> requestTest(ApiService.HandlerModel handlerModel){
        return apiService.requestTest(handlerModel);
    }

    public Observable<JsonObject> requestTest(String Json){
        return apiService.requestTest(Json);
    }

}
